#include<iostream>
#include<vector>
#include<mutex>
#include<thread>
#include<string>
using namespace std;

//class Singleton
//{
//public:
//	static Singleton* Getinstance()
//	{
//	
//		return _instanse;
//
//	}
//	void push(int x)
//	{
//		_mutex.lock();
//		_st.push_back(x);
//		_mutex.unlock();
//	
//	}
//	void print()
//	{
//		_mutex.lock();
//		for (int i = 0; i < _st.size(); i++)
//		{
//			cout << _st[i] << " ";
//
//		}
//
//		_mutex.unlock();
//	
//	
//	
//	
//	}
//
//
//
//
//
//private:
//	Singleton() {}
//	Singleton(const Singleton&) = delete;
//	Singleton & operator=(const Singleton&) = delete;
//
//private:
//	static Singleton* _instanse;
//	vector<int>_st;
//	mutex _mutex;
//
//
//
//};
//Singleton* Singleton::_instanse = new Singleton;
//
//int main()
//{
//
//
//	Singleton::Getinstance()->push(1);
//
//	Singleton::Getinstance()->push(2);
//	Singleton::Getinstance()->push(6);
//	Singleton::Getinstance()->push(7);
//	Singleton::Getinstance()->push(5);
//	Singleton::Getinstance()->push(9);
//	Singleton::Getinstance()->print();
//
//}


class Singleton
{
public:
	static Singleton* Getinstance()
	{
		if (_instanse == nullptr)
		{
			_imutex.lock();
			if (_instanse == nullptr)
			{
				_instanse = new Singleton;

			}
			_imutex.unlock();
		}
		return _instanse;



	}

	static void Destroyed()
	{
		_imutex.lock();
		if (_instanse != nullptr)
		{
			delete _instanse;
			_instanse = nullptr;

		}
		_imutex.unlock();
	
	}

   class GC
	{

	public:
		~GC()
		{
			Destroyed();
		
		}





	};

	static GC gc;


	void push(string x)
	{
		_mutex.lock();
		_st.push_back(x);
		_mutex.unlock();

	}
	void print()
	{
		_mutex.lock();
		for (int i = 0; i< _st.size(); i++)
		{
			cout << _st[i] << endl;

		}

		_mutex.unlock();




	}





private:
	Singleton() {}
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;

private:
	static Singleton* _instanse;
	vector<string>_st;
	static mutex _imutex;
	mutex _mutex;

};
Singleton* Singleton::_instanse = nullptr;
mutex  Singleton::_imutex;
Singleton::GC Singleton::gc;

int main()
{
	int n = 30;
	thread t1([&]()
		{
			for (int i = 0; i < n; i++)
			{
				string str = "thread 1:" + to_string(rand() % (i+1));
				Singleton::Getinstance()->push(str);


			}


		});

	thread t2([&]()
		{
			for (int i = 0; i < 30; i++)
			{
				string str = "thread 2:" + to_string(rand() % (i + 1));
				Singleton::Getinstance()->push(str);


			}


		});
	
	t1.join();
	t2.join();
	Singleton::Getinstance()->print();

}